home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 4 / Amiga Tools 4.iso / tools / dfue / term 4.6(?) / termlite / termlite.c < prev    next >
C/C++ Source or Header  |  1991-08-26  |  19KB  |  691 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1990 by Olaf 'Olsen' Barthel & MXM
  4.  *
  5.  *    Name .....: termLite.c
  6.  *    Created ..: Saturday 8-Jun-91 12:32
  7.  *    Revision .: 0
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    08-Jun-91       Olsen           Created this file!
  12.  *
  13.  * $Revision Header ********************************************************/
  14.  
  15.     /* System includes. */
  16.  
  17. #include <intuition/intuitionbase.h>
  18. #include <workbench/workbench.h>
  19. #include <workbench/startup.h>
  20. #include <devices/console.h>
  21. #include <devices/conunit.h>
  22. #include <devices/serial.h>
  23. #include <exec/execbase.h>
  24. #include <dos/dosextens.h>
  25. #include <exec/memory.h>
  26. #include <dos/rdargs.h>
  27.  
  28. #include <clib/intuition_protos.h>
  29. #include <clib/graphics_protos.h>
  30. #include <clib/icon_protos.h>
  31. #include <clib/exec_protos.h>
  32. #include <clib/dos_protos.h>
  33.  
  34. #include <string.h>
  35. #include <stdarg.h>
  36.  
  37.     /* A handy macro to access AbsExecBase. */
  38.  
  39. #define SysBase        (*(struct ExecBase **)4L)
  40.  
  41.     /* The following pragmas provide the nessary support
  42.      * for reentrancy: they permit to keep the library bases
  43.      * defined locally.
  44.      */
  45.  
  46.     /* exec.library calls. */
  47.  
  48. #pragma libcall SysBase WaitPort 180 801
  49. #pragma libcall SysBase GetMsg 174 801
  50. #pragma libcall SysBase ReplyMsg 17a 901
  51. #pragma libcall SysBase CloseLibrary 19e 901
  52. #pragma libcall SysBase OpenLibrary 228 902
  53. #pragma libcall SysBase AllocVec 2ac 1002
  54. #pragma libcall SysBase FreeVec 2b2 901
  55. #pragma libcall SysBase Forbid 84 0
  56. #pragma libcall SysBase SendIO 1ce 901
  57. #pragma libcall SysBase WaitIO 1da 901
  58. #pragma libcall SysBase AbortIO 1e0 901
  59. #pragma libcall SysBase Wait 13e 1
  60. #pragma libcall SysBase DoIO 1c8 901
  61. #pragma libcall SysBase OpenDevice 1bc 190804
  62. #pragma libcall SysBase CloseDevice 1c2 901
  63. #pragma libcall SysBase CreateIORequest 28e 802
  64. #pragma libcall SysBase DeleteIORequest 294 801
  65. #pragma libcall SysBase CreateMsgPort 29a 0
  66. #pragma libcall SysBase DeleteMsgPort 2a0 801
  67. #pragma libcall SysBase CopyMem 270 9803
  68.  
  69.     /* dos.library calls. */
  70.  
  71. #pragma libcall DOSBase ReadArgs 31E 32103
  72. #pragma libcall DOSBase FreeArgs 35A 101
  73. #pragma libcall DOSBase StrToLong 330 2102
  74. #pragma libcall DOSBase VPrintf 3BA 2102
  75.  
  76.     /* icon.library calls. */
  77.  
  78. #pragma libcall IconBase GetDiskObject 4E 801
  79. #pragma libcall IconBase FreeDiskObject 5A 801
  80. #pragma libcall IconBase FindToolType 60 9802
  81.  
  82.     /* intuition.library calls. */
  83.  
  84. #pragma libcall IntuitionBase LockPubScreen 1FE 801
  85. #pragma libcall IntuitionBase UnlockPubScreen 204 9802
  86. #pragma libcall IntuitionBase OpenWindowTagList 25E 9802
  87. #pragma libcall IntuitionBase CloseWindow 48 801
  88. #pragma libcall IntuitionBase EasyRequestArgs 24C BA9804
  89.  
  90.     /* Signal bits to wait for. */
  91.  
  92. #define SIG_SERIAL    (1 << SerReadPort -> mp_SigBit)
  93. #define SIG_CONSOLE    (1 << ConReadPort -> mp_SigBit)
  94. #define SIG_WINDOW    (1 << Window -> UserPort -> mp_SigBit)
  95.  
  96.     /* Size of the console read buffer and the serial read buffer. */
  97.  
  98. #define CON_READ_SIZE    256
  99. #define SER_READ_SIZE    1024
  100.  
  101.     /* Argument vector offsets. */
  102.  
  103. enum    {    ARG_DEVICE,ARG_UNIT };
  104.  
  105.     /* termLite():
  106.      *
  107.      *    termLite main program, handles all those neat
  108.      *    IO functions in just a single routine.
  109.      */
  110.  
  111. LONG __saveds
  112. termLite(VOID)
  113. {
  114.         /* Window definitions, just a lookup table, will get
  115.          * copied to local stack vars and modified lateron.
  116.          * (to save the relocs).
  117.          */
  118.  
  119.     STATIC ULONG DefaultTags[20 * 2 + 1] =
  120.     {
  121.         WA_Top,            NULL,
  122.         WA_Width,        NULL,
  123.         WA_Height,        NULL,
  124.         WA_MinHeight,        NULL,
  125.         WA_Title,        NULL,
  126.         WA_MinWidth,        NULL,
  127.         WA_MaxWidth,        ~0,
  128.         WA_MaxHeight,        ~0,
  129.         WA_Left,        0,
  130.         WA_SimpleRefresh,    TRUE,
  131.         WA_SizeGadget,        TRUE,
  132.         WA_DragBar,        TRUE,
  133.         WA_DepthGadget,        TRUE,
  134.         WA_CloseGadget,        TRUE,
  135.         WA_Activate,        TRUE,
  136.         WA_RMBTrap,        TRUE,
  137.         WA_SizeBBottom,        TRUE,
  138.         WA_AutoAdjust,        TRUE,
  139.         WA_RMBTrap,        TRUE,
  140.         WA_IDCMP,        IDCMP_CLOSEWINDOW,
  141.  
  142.         TAG_DONE
  143.     };
  144.  
  145.         /* Library bases. */
  146.  
  147.     struct DosLibrary    *DOSBase;
  148.     struct IntuitionBase    *IntuitionBase;
  149.  
  150.         /* Workbench data. */
  151.  
  152.     struct Process        *ThisProcess;
  153.     struct WBStartup    *WBenchMsg;
  154.  
  155.         /* Our window. */
  156.  
  157.     struct Window        *Window;
  158.  
  159.         /* Serial IO data. */
  160.  
  161.     struct IOExtSer        *SerReadRequest;
  162.     struct IOExtSer        *SerWriteRequest;
  163.     struct MsgPort        *SerReadPort;
  164.     struct MsgPort        *SerWritePort;
  165.     APTR             SerReadBuffer;
  166.  
  167.         /* Console IO data. */
  168.  
  169.     struct IOStdReq        *ConReadRequest;
  170.     struct IOStdReq        *ConWriteRequest;
  171.     struct MsgPort        *ConReadPort;
  172.     struct MsgPort        *ConWritePort;
  173.     APTR             ConReadBuffer;
  174.  
  175.         /* Global result code. */
  176.  
  177.     LONG             Result = RETURN_FAIL;
  178.  
  179.         /* Set up the process pointer. */
  180.  
  181.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  182.  
  183.         /* Wait for Workbench startup packet. */
  184.  
  185.     if(!ThisProcess -> pr_CLI)
  186.     {
  187.         WaitPort(&ThisProcess -> pr_MsgPort);
  188.  
  189.         WBenchMsg = (struct WBStartup *)GetMsg(&ThisProcess -> pr_MsgPort);
  190.     }
  191.     else
  192.         WBenchMsg = NULL;
  193.  
  194.         /* Are we running under control of Kickstart 2.0? */
  195.  
  196.     if(SysBase -> LibNode . lib_Version >= 37)
  197.     {
  198.             /* Open dos.library. */
  199.  
  200.         if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))
  201.         {
  202.                 /* Open intuition.library. */
  203.  
  204.             if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37))
  205.             {
  206.                 UBYTE    DeviceName[40];
  207.                 LONG    UnitNumber;
  208.  
  209.                     /* Fill in the default serial device
  210.                      * name.
  211.                      */
  212.  
  213.                 strcpy(DeviceName,SERIALNAME);
  214.  
  215.                     /* And set the default unit number
  216.                      * to zero.
  217.                      */
  218.  
  219.                 UnitNumber = 0;
  220.  
  221.                     /* Take a look at the tool icon
  222.                      * if run from Workbench.
  223.                      */
  224.  
  225.                 if(WBenchMsg)
  226.                 {
  227.                     struct Library *IconBase;
  228.  
  229.                         /* Open icon.library. */
  230.  
  231.                     if(IconBase = OpenLibrary("icon.library",0))
  232.                     {
  233.                         struct DiskObject *DiskObject;
  234.  
  235.                             /* Read the tool icon. */
  236.  
  237.                         if(DiskObject = GetDiskObject(WBenchMsg -> sm_ArgList -> wa_Name))
  238.                         {
  239.                             UBYTE *Entry;
  240.  
  241.                                 /* Check for custom device name. */
  242.  
  243.                             if(Entry = FindToolType(DiskObject -> do_ToolTypes,"DEVICE"))
  244.                                 strcpy(DeviceName,Entry);
  245.  
  246.                                 /* Check for custom device number. */
  247.  
  248.                             if(Entry = FindToolType(DiskObject -> do_ToolTypes,"UNIT"))
  249.                                 StrToLong(Entry,&UnitNumber);
  250.  
  251.                                 /* Release the icon. */
  252.  
  253.                             FreeDiskObject(DiskObject);
  254.                         }
  255.  
  256.                             /* Close the library. */
  257.  
  258.                         CloseLibrary(IconBase);
  259.                     }
  260.                 }
  261.                 else
  262.                 {
  263.                     UBYTE **ArgArray;
  264.  
  265.                         /* Allocate argument array. */
  266.  
  267.                     if(ArgArray = (UBYTE **)AllocVec(sizeof(UBYTE *) * 2,MEMF_PUBLIC|MEMF_CLEAR))
  268.                     {
  269.                         struct RDArgs *ArgsPtr;
  270.  
  271.                             /* Read the startup args if any. */
  272.  
  273.                         if(ArgsPtr = (struct RDArgs *)ReadArgs("D=Device/K,U=Unit/N/K",(LONG *)ArgArray,NULL))
  274.                         {
  275.                                 /* Set custom device name. */
  276.  
  277.                             if(ArgArray[ARG_DEVICE])
  278.                                 strcpy(DeviceName,ArgArray[ARG_DEVICE]);
  279.  
  280.                                 /* Set custom unit number. */
  281.  
  282.                             if(ArgArray[ARG_UNIT])
  283.                                 UnitNumber = *(LONG *)ArgArray[ARG_UNIT];
  284.  
  285.                                 /* Free the args. */
  286.  
  287.                             FreeArgs(ArgsPtr);
  288.                         }
  289.  
  290.                             /* Free the argument array. */
  291.  
  292.                         FreeVec(ArgArray);
  293.                     }
  294.                 }
  295.  
  296.                     /* Allocate the serial read buffer. */
  297.  
  298.                 if(SerReadBuffer = AllocVec(SER_READ_SIZE,MEMF_PUBLIC))
  299.                 {
  300.                         /* Create the serial read port. */
  301.  
  302.                     if(SerReadPort = CreateMsgPort())
  303.                     {
  304.                             /* Create the serial write port. */
  305.  
  306.                         if(SerWritePort = CreateMsgPort())
  307.                         {
  308.                                 /* Create the serial read request. */
  309.  
  310.                             if(SerReadRequest = (struct IOExtSer *)CreateIORequest(SerReadPort,sizeof(struct IOExtSer)))
  311.                             {
  312.                                     /* Create the serial write request. */
  313.  
  314.                                 if(SerWriteRequest = (struct IOExtSer *)AllocVec(sizeof(struct IOExtSer),MEMF_PUBLIC))
  315.                                 {
  316.                                         /* Open the device in shared mode. */
  317.  
  318.                                     SerReadRequest -> io_SerFlags |= SERF_SHARED;
  319.  
  320.                                     if(!OpenDevice(DeviceName,UnitNumber,&SerReadRequest -> IOSer,0))
  321.                                     {
  322.                                             /* Clone the IORequest and fill in the
  323.                                              * approriate reply port for the write
  324.                                              * request.
  325.                                              */
  326.  
  327.                                         CopyMem(SerReadRequest,SerWriteRequest,sizeof(struct IOExtSer));
  328.  
  329.                                         SerWriteRequest -> IOSer . io_Message . mn_ReplyPort = SerWritePort;
  330.  
  331.                                             /* Allocate the console read buffer. */
  332.  
  333.                                         if(ConReadBuffer = AllocVec(CON_READ_SIZE,MEMF_PUBLIC))
  334.                                         {
  335.                                             struct Screen *DefaultScreen;
  336.  
  337.                                                 /* Lock the default public screen. */
  338.  
  339.                                             if(DefaultScreen = LockPubScreen(NULL))
  340.                                             {
  341.                                                 ULONG StackTags[20 * 2 + 1];
  342.  
  343.                                                     /* Copy window sestup tags to local
  344.                                                      * stack array and initialize it
  345.                                                      * according to the size and
  346.                                                      * characteristics of the default
  347.                                                      * screen.
  348.                                                      */
  349.  
  350.                                                 CopyMem(DefaultTags,StackTags,sizeof(DefaultTags));
  351.  
  352.                                                 StackTags[ 1] = DefaultScreen -> BarHeight + 1;
  353.                                                 StackTags[ 3] = DefaultScreen -> Width;
  354.                                                 StackTags[ 5] = (DefaultScreen -> Font -> ta_YSize) * 17 + DefaultScreen -> WBorTop + DefaultScreen -> WBorBottom + 1;
  355.                                                 StackTags[ 7] = DefaultScreen -> Font -> ta_YSize + DefaultScreen -> WBorTop + DefaultScreen -> WBorBottom - 1;
  356.                                                 StackTags[ 9] = (ULONG)("termLite © Copyright 1991 by MXM");
  357.                                                 StackTags[11] = DefaultScreen -> Width >> 1;
  358.  
  359.                                                     /* Open the window. */
  360.  
  361.                                                 if(Window = OpenWindowTagList(NULL,(struct TagItem *)&StackTags[0]))
  362.                                                 {
  363.                                                         /* Create the console read port. */
  364.  
  365.                                                     if(ConReadPort = CreateMsgPort())
  366.                                                     {
  367.                                                             /* Create the console write port. */
  368.  
  369.                                                         if(ConWritePort = CreateMsgPort())
  370.                                                         {
  371.                                                                 /* Create the console read
  372.                                                                  * request.
  373.                                                                  */
  374.  
  375.                                                             if(ConReadRequest = (struct IOStdReq *)CreateIORequest(ConReadPort,sizeof(struct IOStdReq)))
  376.                                                             {
  377.                                                                     /* Create the console write request. */
  378.  
  379.                                                                 if(ConWriteRequest = (struct IOStdReq *)AllocVec(sizeof(struct IOStdReq),MEMF_PUBLIC))
  380.                                                                 {
  381.                                                                         /* Set up the console startup information and
  382.                                                                          * open the approriate device.
  383.                                                                          */
  384.  
  385.                                                                     ConReadRequest -> io_Data    = Window;
  386.                                                                     ConReadRequest -> io_Length    = sizeof(struct Window *);
  387.  
  388.                                                                         /* We want the character mapped simple refresh window
  389.                                                                          * including cut & paste.
  390.                                                                          */
  391.  
  392.                                                                     if(!OpenDevice("console.device",CONU_SNIPMAP,ConReadRequest,0))
  393.                                                                     {
  394.                                                                         BYTE    Terminated = FALSE;
  395.                                                                         ULONG    SignalSet;
  396.  
  397.                                                                             /* Clone the IORequest and
  398.                                                                              * fill in the console write
  399.                                                                              * port.
  400.                                                                              */
  401.  
  402.                                                                         CopyMem(ConReadRequest,ConWriteRequest,sizeof(struct IOStdReq));
  403.  
  404.                                                                         ConWriteRequest -> io_Message . mn_ReplyPort = ConWritePort;
  405.  
  406.                                                                             /* Unlock the default public
  407.                                                                              * screen, there probably
  408.                                                                              * is no need to keep
  409.                                                                              * it open (our window
  410.                                                                              * will keep it from
  411.                                                                              * closing).
  412.                                                                              */
  413.  
  414.                                                                         UnlockPubScreen(NULL,DefaultScreen);
  415.  
  416.                                                                         DefaultScreen = NULL;
  417.  
  418.                                                                             /* Request characters from the console window. */
  419.  
  420.                                                                         ConReadRequest -> io_Command        = CMD_READ;
  421.                                                                         ConReadRequest -> io_Length        = CON_READ_SIZE - 1;
  422.                                                                         ConReadRequest -> io_Data        = ConReadBuffer;
  423.  
  424.                                                                         SendIO(ConReadRequest);
  425.  
  426.                                                                             /* Request a single byte from the
  427.                                                                              * serial line.
  428.                                                                              */
  429.  
  430.                                                                         SerReadRequest -> IOSer . io_Command    = CMD_READ;
  431.                                                                         SerReadRequest -> IOSer . io_Length    = 1;
  432.                                                                         SerReadRequest -> IOSer . io_Data    = SerReadBuffer;
  433.  
  434.                                                                         SendIO(&SerReadRequest -> IOSer);
  435.  
  436.                                                                         Result = RETURN_OK;
  437.  
  438.                                                                             /* Go into loop until the
  439.                                                                              * user hits the close
  440.                                                                              * gadget.
  441.                                                                              */
  442.  
  443.                                                                         while(!Terminated)
  444.                                                                         {
  445.                                                                                 /* Wait for signals. */
  446.  
  447.                                                                             SignalSet = Wait(SIG_SERIAL | SIG_CONSOLE | SIG_WINDOW);
  448.  
  449.                                                                                 /* Did we get a message from the window? */
  450.  
  451.                                                                             if(SignalSet & SIG_WINDOW)
  452.                                                                             {
  453.                                                                                 struct IntuiMessage *Massage;
  454.  
  455.                                                                                     /* Pick up the messages and reply them. The
  456.                                                                                      * only message type we expect is the
  457.                                                                                      * IDCMP_CLOSEWINDOW type.
  458.                                                                                      */
  459.  
  460.                                                                                 while(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  461.                                                                                 {
  462.                                                                                     ReplyMsg(&Massage -> ExecMessage);
  463.  
  464.                                                                                     Terminated = TRUE;
  465.                                                                                 }
  466.                                                                             }
  467.  
  468.                                                                                 /* Did we get a message from the
  469.                                                                                  * console?
  470.                                                                                  */
  471.  
  472.                                                                             if(SignalSet & SIG_CONSOLE)
  473.                                                                             {
  474.                                                                                     /* Remove the IORequest from
  475.                                                                                      * the message list.
  476.                                                                                      */
  477.  
  478.                                                                                 WaitIO(ConReadRequest);
  479.  
  480.                                                                                     /* Send the resulting characters to the
  481.                                                                                      * serial device.
  482.                                                                                      */
  483.  
  484.                                                                                 SerWriteRequest -> IOSer . io_Command    = CMD_WRITE;
  485.                                                                                 SerWriteRequest -> IOSer . io_Data    = ConReadBuffer;
  486.                                                                                 SerWriteRequest -> IOSer . io_Length    = ConReadRequest -> io_Actual;
  487.  
  488.                                                                                 DoIO(&SerWriteRequest -> IOSer);
  489.  
  490.                                                                                     /* Post another request to the
  491.                                                                                      * console.
  492.                                                                                      */
  493.  
  494.                                                                                 ConReadRequest -> io_Command        = CMD_READ;
  495.                                                                                 ConReadRequest -> io_Length        = CON_READ_SIZE - 1;
  496.                                                                                 ConReadRequest -> io_Data        = ConReadBuffer;
  497.  
  498.                                                                                 SendIO(ConReadRequest);
  499.                                                                             }
  500.  
  501.                                                                                 /* Did we get a signal from
  502.                                                                                  * the serial line?
  503.                                                                                  */
  504.  
  505.                                                                             if(SignalSet & SIG_SERIAL)
  506.                                                                             {
  507.                                                                                 LONG Size;
  508.  
  509.                                                                                     /* Remove IORequest from the
  510.                                                                                      * message list.
  511.                                                                                      */
  512.  
  513.                                                                                 WaitIO(&SerReadRequest -> IOSer);
  514.  
  515.                                                                                     /* Echo the single character to
  516.                                                                                      * the console.
  517.                                                                                      */
  518.  
  519.                                                                                 ConWriteRequest -> io_Command    = CMD_WRITE;
  520.                                                                                 ConWriteRequest -> io_Data    = SerReadBuffer;
  521.                                                                                 ConWriteRequest -> io_Length    = 1;
  522.  
  523.                                                                                 DoIO(ConWriteRequest);
  524.  
  525.                                                                                     /* Inquire how many characters
  526.                                                                                      * are still pending at the
  527.                                                                                      * serial port.
  528.                                                                                      */
  529.  
  530.                                                                                 SerReadRequest -> IOSer . io_Command = SDCMD_QUERY;
  531.  
  532.                                                                                 DoIO(&SerReadRequest -> IOSer);
  533.  
  534.                                                                                     /* If there are any, transfer them to
  535.                                                                                      * the serial line.
  536.                                                                                      */
  537.  
  538.                                                                                 if(Size = SerReadRequest -> IOSer . io_Actual)
  539.                                                                                 {
  540.                                                                                     LONG Frag;
  541.  
  542.                                                                                         /* We need to transfer the block in small
  543.                                                                                          * fragments since the serial read buffer
  544.                                                                                          * may be smaller than the amount of data
  545.                                                                                          * to be read.
  546.                                                                                          */
  547.  
  548.                                                                                     while(Size)
  549.                                                                                     {
  550.                                                                                             /* Determine number of bytes to read. */
  551.  
  552.                                                                                         Frag = Size > SER_READ_SIZE ? SER_READ_SIZE : Size;
  553.  
  554.                                                                                             /* Read the bytes. */
  555.  
  556.                                                                                         SerReadRequest -> IOSer . io_Command    = CMD_READ;
  557.                                                                                         SerReadRequest -> IOSer . io_Data    = SerReadBuffer;
  558.                                                                                         SerReadRequest -> IOSer . io_Length    = Frag;
  559.  
  560.                                                                                         DoIO(&SerReadRequest -> IOSer);
  561.  
  562.                                                                                             /* Transfer them to the window. */
  563.  
  564.                                                                                         ConWriteRequest -> io_Command        = CMD_WRITE;
  565.                                                                                         ConWriteRequest -> io_Data        = SerReadBuffer;
  566.                                                                                         ConWriteRequest -> io_Length        = Frag;
  567.  
  568.                                                                                         DoIO(ConWriteRequest);
  569.  
  570.                                                                                         Size -= Frag;
  571.                                                                                     }
  572.                                                                                 }
  573.  
  574.                                                                                     /* Post a request for another byte. */
  575.  
  576.                                                                                 SerReadRequest -> IOSer . io_Command    = CMD_READ;
  577.                                                                                 SerReadRequest -> IOSer . io_Data    = SerReadBuffer;
  578.                                                                                 SerReadRequest -> IOSer . io_Length    = 1;
  579.  
  580.                                                                                 SendIO(&SerReadRequest -> IOSer);
  581.                                                                             }
  582.                                                                         }
  583.  
  584.                                                                             /* The program has been flagged to
  585.                                                                              * to close down. Abort the pending
  586.                                                                              * IORequestes and close the
  587.                                                                              * console device.
  588.                                                                              */
  589.  
  590.                                                                         AbortIO(ConReadRequest);
  591.                                                                         WaitIO(ConReadRequest);
  592.  
  593.                                                                         AbortIO(&SerReadRequest -> IOSer);
  594.                                                                         WaitIO(&SerReadRequest -> IOSer);
  595.  
  596.                                                                         CloseDevice(ConReadRequest);
  597.                                                                     }
  598.  
  599.                                                                         /* Free the console write request. */
  600.  
  601.                                                                     FreeVec(ConWriteRequest);
  602.                                                                 }
  603.  
  604.                                                                     /* Free the console read request. */
  605.  
  606.                                                                 DeleteIORequest(ConReadRequest);
  607.                                                             }
  608.  
  609.                                                                 /* Delete the console write port. */
  610.  
  611.                                                             DeleteMsgPort(ConWritePort);
  612.                                                         }
  613.  
  614.                                                             /* Delete the console read port. */
  615.  
  616.                                                         DeleteMsgPort(ConReadPort);
  617.                                                     }
  618.  
  619.                                                         /* Close the window. */
  620.  
  621.                                                     CloseWindow(Window);
  622.                                                 }
  623.  
  624.                                                     /* Unlock the default public screen
  625.                                                      * if necessary.
  626.                                                      */
  627.  
  628.                                                 if(DefaultScreen)
  629.                                                     UnlockPubScreen(NULL,DefaultScreen);
  630.                                             }
  631.  
  632.                                                 /* Free the console read buffer. */
  633.  
  634.                                             FreeVec(ConReadBuffer);
  635.                                         }
  636.  
  637.                                             /* Close the serial device. */
  638.  
  639.                                         CloseDevice(&SerReadRequest -> IOSer);
  640.                                     }
  641.  
  642.                                         /* Free the serial write request. */
  643.  
  644.                                     FreeVec(SerWriteRequest);
  645.                                 }
  646.  
  647.                                     /* Free the serial read request. */
  648.  
  649.                                 DeleteIORequest(SerReadRequest);
  650.                             }
  651.  
  652.                                 /* Delete the serial write port. */
  653.  
  654.                             DeleteMsgPort(SerWritePort);
  655.                         }
  656.  
  657.                             /* Delete the serial read port. */
  658.  
  659.                         DeleteMsgPort(SerReadPort);
  660.                     }
  661.  
  662.                         /* Delete the serial read buffer. */
  663.  
  664.                     FreeVec(SerReadBuffer);
  665.                 }
  666.  
  667.                     /* Close intuition.library. */
  668.  
  669.                 CloseLibrary(&IntuitionBase -> LibNode);
  670.             }
  671.  
  672.                 /* Close dos.library. */
  673.  
  674.             CloseLibrary(&DOSBase -> dl_lib);
  675.         }
  676.     }
  677.  
  678.         /* Reply the startup packet if necessary. */
  679.  
  680.     if(WBenchMsg)
  681.     {
  682.         Forbid();
  683.  
  684.         ReplyMsg(&WBenchMsg -> sm_Message);
  685.     }
  686.  
  687.         /* Return the result. */
  688.  
  689.     return(Result);
  690. }
  691.